home *** CD-ROM | disk | FTP | other *** search
Oberon Text | 1995-08-29 | 34.2 KB | 935 lines | [TEXT/.Ob4] |
- Syntax10b.Scn.Fnt
- Syntax10.Scn.Fnt
- Syntax10i.Scn.Fnt
- InfoElems
- Alloc
- Syntax10.Scn.Fnt
- StampElems
- Alloc
- 29 Aug 95
- "Title": POPV
- "Author": RC/ mmb
- "Abstract":
- "Keywords":
- "Version":
- "From": RC 6.3.89 / 28.8.91, mmb11.2.93
- "Until":
- "Changes":
- mah 14.8.95 Fehler in ActualPar. Dynarr als Stackparameter => Laenge und Adr in selben Register
- mah 14.8.95 Fehler in Stringhandling. alignment exception possible weil nicht auf mod 4 ausgerichtet.
- MODULE POPV; (* RC 6.3.89 / 28.8.91, mmb11.2.93 *)
- IMPORT
- OPT := POPT, OPL := POPL, OPC := POPC, OPM := POPM, SYSTEM;
- CONST
- (* item/object modes *)
- Var = 1; VarPar = 2; Con = 3; Fld = 4; Typ = 5; LProc = 6; XProc = 7;
- SProc = 8; CProc = 9; Mod = 11; IProc = 10; Head = 12; TProc = 13;
- Based = 14; Indexed = 15; Reg = 16; RegSI = 17; FReg = 18; Cond = 19;
- (* symbol values and ops *)
- times = 1; slash = 2; div = 3; mod = 4;
- and = 5; plus = 6; minus = 7; or = 8; eql = 9;
- neq = 10; lss = 11; leq = 12; gtr = 13; geq = 14;
- in = 15; is = 16; ash = 17; msk = 18; len = 19;
- conv = 20; abs = 21; cap = 22; odd = 23; not = 33;
- (*SYSTEM*)
- adr = 24; cc = 25; bit = 26; lsh = 27; rot = 28; val = 29;
- (* structure forms *)
- Undef = 0; Byte = 1; Bool = 2; Char = 3; SInt = 4; Int = 5; LInt = 6;
- Real = 7; LReal = 8; Set = 9; String = 10; NilTyp = 11; NoTyp = 12;
- Pointer = 13; ProcTyp = 14; Comp = 15;
- (* structure sets *)
- RealTypes = {Real, LReal};
- (* composite structure forms *)
- Basic = 1; Array = 2; DynArr = 3; Record = 4;
- (* nodes classes *)
- Nvar = 0; Nvarpar = 1; Nfield = 2; Nderef = 3; Nindex = 4; Nguard = 5; Neguard = 6;
- Nconst = 7; Ntype = 8; Nproc = 9; Nupto = 10; Nmop = 11; Ndop = 12; Ncall = 13;
- Ninittd = 14; Nif = 15; Ncaselse = 16; Ncasedo = 17; Nenter = 18; Nassign = 19;
- Nifelse =20; Ncase = 21; Nwhile = 22; Nrepeat = 23; Nloop = 24; Nexit = 25;
- Nreturn = 26; Nwith = 27; Ntrap = 28; Ncommon = 29;
- (*function number*)
- assign = 0; newfn = 1; incfn = 13; decfn = 14;
- inclfn = 15; exclfn = 16; copyfn = 18; assertfn = 32;
- (*SYSTEM function number*)
- getfn = 24; putfn = 25; getrfn = 26; putrfn = 27; sysnewfn = 30; movefn = 31;
- (* module visibility of objects *)
- internal = 0; external = 1; externalR = 2;
- (* procedure flags (conval^.setval) *)
- hasBody = 1; isRedef = 2; slNeeded = 3;
- DoCommonDesign = TRUE; (* identify same designators not containing expressions: design := design op expr *)
- (* machine specific stuff *)
- (* condition code bits *)
- bLT = 0; bGT = 1; bEQ = 2; bSO = 3;
- (* trap numbers *)
- IndexCheck = 1; DivideTrap = 2; CaseTrap = 3; TypeGuard = 4; FuncTrap = 5;
- memTag = 1024; (* (linkadr > memtag) => parameter passed in memory *)
- SP = 1; FP = 31;
- TYPE
- Stats* = POINTER TO StatsBlock; (* debugger info *)
- StatsBlock* = RECORD
- pc-: ARRAY 128 OF SHORTINT; (* relative pc to last pc. PC's divided by 4 *)
- pos-: ARRAY 128 OF LONGINT; (* absolute position in source *)
- numStat-: INTEGER;
- next-: Stats;
- END;
- levCall: INTEGER;
- CommonDesign: OPL.Item;
- CommonDesignClass: SHORTINT;
- assert, findpc, powerpc: BOOLEAN;
- stats*, curStats: Stats; (* debugger info *)
- decPC, lastErr, lastClass: LONGINT;
- PROCEDURE FlipBytes (VAR b: ARRAY OF SYSTEM.BYTE);
- VAR i, j: INTEGER; h: SYSTEM.BYTE;
- BEGIN
- IF OPM.CeresVersion THEN
- i := 0; j := SHORT(LEN(b))-1;
- WHILE i < j DO h := b[i]; b[i] := b[j]; b[j] := h; INC(i); DEC(j) END
- END
- END FlipBytes;
- PROCEDURE Align (VAR offset: LONGINT; base: INTEGER);
- BEGIN
- CASE base OF
- 1: (* ok *)
- | 2: INC(offset, offset MOD 2)
- | 4: INC(offset, (-offset) MOD 4)
- | 8: INC(offset, (-offset) MOD 8)
- END
- END Align;
- PROCEDURE ^ParamAdr (firstPar: OPT.Object; VAR parSize, varSize: LONGINT; VAR parRegs: SET);
- PROCEDURE Base (typ: OPT.Struct): INTEGER; (* typ^.comp # DynArr *)
- VAR array: BOOLEAN; (* mah *)
- BEGIN
- array := typ.comp = Array; (* mah *)
- WHILE typ^.comp = Array DO typ := typ^.BaseTyp END ;
- IF typ^.comp = Record THEN RETURN ABS(typ^.sysflag) (*!!!*)
- ELSIF typ^.form = ProcTyp THEN RETURN 4
- ELSIF array & (typ.form = Char) THEN RETURN 4 (* mah *)
- ELSE RETURN SHORT(typ^.size)
- END
- END Base;
- PROCEDURE^ Traverse (obj: OPT.Object; exported: BOOLEAN);
- PROCEDURE ^VisitTProcs (obj: OPT.Object);
- PROCEDURE TypSize* (typ: OPT.Struct; allocDesc: BOOLEAN);
- VAR
- f, c, base, fbase: INTEGER;
- offset, size, n, dims: LONGINT;
- dval: SET;
- fld: OPT.Object;
- btyp: OPT.Struct;
- sizeUndef, doAlloc: BOOLEAN;
- BEGIN
- IF typ = OPT.undftyp THEN OPM.err(58)
- ELSE
- sizeUndef := typ^.size = -1;
- doAlloc := allocDesc & (typ^.tdadr = OPM.TDAdrUndef) & (typ^.offset = OPM.TDAdrUndef);
- IF sizeUndef OR doAlloc THEN
- IF doAlloc THEN typ^.tdadr := -2 (* avoid cycles *) END ;
- f := typ^.form; c := typ^.comp; btyp := typ^.BaseTyp;
- IF c = Record THEN
- IF typ^.sysflag = 1 THEN typ^.sysflag := -2 END; (*!!!*)
- IF btyp = NIL THEN offset := 0; base := 1
- ELSE TypSize(btyp, allocDesc); offset := btyp^.size; base := btyp^.sysflag
- END;
- IF btyp = NIL THEN typ^.n := 0 ELSE typ^.n := btyp^.n END ;
- VisitTProcs(typ^.link);
- fld := typ^.link;
- WHILE (fld # NIL) & (fld^.mode = Fld) DO
- btyp := fld^.typ; TypSize(btyp, allocDesc);
- IF sizeUndef THEN size := btyp^.size;
- fbase := Base(btyp);
- IF (typ^.sysflag < 0) & (fbase > 2) THEN Align(offset, 2) ELSE Align(offset, fbase) END; (*!!!*)
- fld^.adr := offset; INC(offset, size);
- IF fbase > base THEN base := fbase END
- END ;
- fld := fld^.link
- END ;
- IF sizeUndef THEN
- IF typ^.sysflag >= 0 THEN Align(offset, base); typ^.sysflag := base END; (*!!!*)
- typ^.size := offset
- END ;
- IF doAlloc THEN OPL.AllocTypDesc(typ); Traverse(typ^.link, TRUE) END
- ELSIF c = Array THEN
- TypSize(btyp, allocDesc);
- IF (btyp^.sysflag < 0) & (btyp^.size MOD 4 # 0) THEN OPM.err(252) END; (*!!!*)
- IF sizeUndef THEN typ^.size := typ^.n * btyp^.size END
- ELSIF f = Pointer THEN
- typ^.size := OPM.PointerSize;
- IF doAlloc THEN TypSize(btyp, allocDesc) END
- ELSIF f = ProcTyp THEN
- typ^.size := OPM.ProcSize;
- IF doAlloc THEN TypSize(btyp, TRUE); ParamAdr(typ^.link, offset, size, dval) END
- (* offset, size and dval are dummies *)
- ELSE (* (c = DynArr) & doAlloc *)
- n := typ^.n; dims := n + 1; btyp := typ;
- WHILE n >= 0 DO
- btyp^.offset := 4*(dims-n); btyp^.size := 4*n + 8;
- btyp := btyp^.BaseTyp; DEC(n)
- END;
- TypSize(btyp, allocDesc)
- END
- END
- END
- END TypSize;
- PROCEDURE ParamAdr (firstPar: OPT.Object; VAR parSize, varSize: LONGINT; VAR parRegs: SET);
- VAR
- par: OPT.Object; typ: OPT.Struct;
- padr, vadr: LONGINT; f, c: INTEGER; pused: SET;
- PROCEDURE Alloc (ps, vs: LONGINT);
- BEGIN
- IF (par^.mode # VarPar) & (typ^.form IN {Real, LReal}) & (f <= 13) THEN
- par^.adr := -1-(FReg*32+f); INCL(pused, f+16); INC(f)
- ELSIF (padr + ps <= 11*4) THEN
- par^.adr := -1-(Reg*32+padr DIV 4); pused := pused + {(padr+4) DIV 4 .. (padr+ps) DIV 4}
- ELSE par^.adr := padr+12
- END;
- IF vs = 0 THEN par^.linkadr := memTag+padr-12
- ELSE Align(vadr, Base(typ)); par^.linkadr := vadr; INC(vadr, vs)
- END;
- INC(padr, ps)
- END Alloc;
- BEGIN
- padr := 3*4; vadr := 0; par := firstPar; f := 1; pused := parRegs;
- WHILE par # NIL DO
- typ := par^.typ; c := typ^.comp; TypSize(typ, TRUE);
- IF c = DynArr THEN Alloc(typ^.size, 0)
- ELSIF par^.mode = VarPar THEN
- IF c = Record THEN Alloc(8, 0)
- ELSE Alloc(4, 0)
- END
- ELSE
- IF c IN {Record, Array} THEN Alloc(4, typ^.size)
- ELSIF typ^.form IN {LReal, ProcTyp} THEN Alloc(8, 0)
- ELSE Alloc(4, 0)
- END
- END;
- par := par^.link
- END;
- DEC(padr, 3*4); Align(padr, 8); Align(vadr, 8); parSize := padr*10000H; varSize := vadr; parRegs := pused
- END ParamAdr;
- PROCEDURE VarAdr (var: OPT.Object; VAR varSize: LONGINT);
- VAR adr: LONGINT; typ: OPT.Struct;
- BEGIN adr := varSize;
- WHILE var # NIL DO
- typ := var^.typ; TypSize(typ, TRUE);
- Align(adr, Base(typ)); var^.adr := adr; var^.linkadr := adr; INC(adr, typ^.size);
- var := var^.link
- END;
- Align(adr, 8); varSize := adr
- END VarAdr;
- PROCEDURE ProcSize (obj: OPT.Object; firstpass: BOOLEAN);
- VAR oldPos: LONGINT;
- BEGIN
- oldPos := OPM.errpos; OPM.errpos := obj^.scope^.adr;
- TypSize(obj^.typ, TRUE);
- IF ((obj^.vis # internal) = firstpass) OR (obj^.mode = TProc) THEN
- IF obj^.mode IN {XProc, IProc, TProc} THEN
- IF OPL.entno < OPL.MaxEntry THEN INC(obj^.adr, LONG(OPL.entno)); INC(OPL.entno)
- ELSE OPM.err(226); obj^.adr := 1
- END
- ELSE obj^.adr := -1 (* entry address undef *)
- END;
- TypSize(obj^.typ, TRUE);
- ParamAdr(obj^.link, obj^.conval^.intval, obj^.conval^.intval2, obj^.conval^.setval);
- obj^.linkadr := OPM.LANotAlloc;
- END ;
- IF ~firstpass OR (obj^.mode = TProc) THEN
- IF ~(hasBody IN obj^.conval^.setval) THEN (* forward *) OPM.err(129) END;
- VarAdr(obj^.scope^.scope, obj^.conval^.intval2); (* local variables *)
- Traverse(obj^.scope^.right, FALSE)
- END;
- OPM.errpos := oldPos
- END ProcSize;
- PROCEDURE VisitTProcs (obj: OPT.Object); (* TProcs of base type already visited *)
- VAR typ: OPT.Struct; redef: OPT.Object; mthno: LONGINT;
- BEGIN
- IF obj # NIL THEN
- VisitTProcs(obj^.left);
- IF obj^.mode = TProc THEN
- typ := obj^.link^.typ;
- IF typ^.form = Pointer THEN typ := typ^.BaseTyp END ;
- OPT.FindField(obj^.name, typ^.BaseTyp, redef);
- IF redef # NIL THEN mthno := redef^.adr DIV 10000H;
- IF ~(isRedef IN obj^.conval^.setval) THEN OPM.err(119) END
- ELSE mthno := typ^.n; INC(typ^.n)
- END;
- obj^.adr := (obj^.adr MOD 10000H) (*entno*) + mthno * 10000H
- END ;
- VisitTProcs(obj^.right)
- END
- END VisitTProcs;
- PROCEDURE Traverse (obj: OPT.Object; exported: BOOLEAN);
- BEGIN
- IF obj # NIL THEN
- Traverse(obj^.left, exported);
- IF (obj^.mode = Typ) & ((obj^.vis # internal) = exported) THEN TypSize(obj^.typ, TRUE)
- ELSIF obj^.mode IN {LProc, XProc, TProc, CProc, IProc} THEN ProcSize(obj, exported)
- END ;
- Traverse(obj^.right, exported);
- END
- END Traverse;
- PROCEDURE AdrAndSize* (topScope: OPT.Object);
- VAR gvarSize: LONGINT;
- BEGIN
- OPM.errpos := topScope^.adr; (* text position of scope used if error *)
- Traverse(topScope^.right, TRUE); (* first pass only on exported types and procedures *)
- gvarSize := (* OPT.nofGmod*4+4; *) 0;
- VarAdr(topScope^.scope, gvarSize); (* global variables *)
- OPL.dsize := gvarSize;
- Traverse(topScope^.right, FALSE); (* second pass on non-exported types and procedures *)
- OPL.AllocLinkTable(OPT.nofGmod+1)
- END AdrAndSize;
- PROCEDURE SameDesign (n1, n2: OPT.Node): BOOLEAN;
- BEGIN
- LOOP
- IF (n1^.class # n2^.class) OR (n1^.typ # n2^.typ) THEN RETURN FALSE END ;
- CASE n1^.class OF
- Nvar, Nvarpar, Nproc: RETURN n1^.obj = n2^.obj
- | Nfield:
- IF n1^.obj # n2^.obj THEN RETURN FALSE END
- | Nderef, Nguard:
- | Nindex:
- IF ~SameDesign(n1^.right, n2^.right) THEN RETURN FALSE END
- ELSE RETURN FALSE
- END ;
- n1 := n1^.left; n2 := n2^.left
- END
- END SameDesign;
- PROCEDURE^ expr (n: OPT.Node; VAR x: OPL.Item; rt: LONGINT);
- PROCEDURE design (n: OPT.Node; VAR x: OPL.Item; rt: LONGINT);
- VAR
- obj: OPT.Object; y: OPL.Item;
- t: LONGINT; class, mode: INTEGER;
- VarRec: BOOLEAN;
- BEGIN
- class := n^.class; x.typ := n^.typ;
- CASE class OF
- Nvar, Nvarpar:
- obj := n^.obj; x.mnolev := obj^.mnolev; t := obj^.linkadr;
- IF x.mnolev < 0 THEN t := obj^.adr END;
- IF t < -1 THEN
- t := -1-t; mode := SHORT(t DIV 32); x.reg := t MOD 32;
- IF (mode = Reg) & (class = Nvarpar) & (n^.typ^.comp # DynArr) THEN
- x.mode := Based; x.offset := 0
- ELSE x.mode := SHORT(mode)
- END
- ELSE x.offset := t; x.adr := obj^.adr; mode := obj^.mode; x.mode := SHORT(mode); x.reg := 0
- END;
- x.dmode := SHORT(mode); x.dreg := -1
- | Nfield:
- t := rt;
- IF (n.typ^.form IN {Real, LReal}) OR (n.typ^.form = ProcTyp) & (rt > 12) THEN t := -1 END;
- (* very temporary patch to make proc calls as well as assignments work right *)
- design(n^.left, x, t); OPC.Field(x, n^.obj^.adr, -1)
- | Nderef:
- design(n^.left, x, rt); OPC.Deref(x, rt);
- IF n^.typ^.comp = DynArr THEN x.dmode := Based END
- | Nindex:
- design(n^.left, x, -1); expr(n^.right, y, -1); OPC.Index(x, y, -1)
- | Nguard:
- VarRec := (n^.left^.class = Nvarpar) & (n^.left^.typ^.comp = Record);
- design(n^.left, x, rt); OPC.TypTest(x, n^.typ, TRUE, FALSE, VarRec)
- | Neguard:
- VarRec := (n^.left^.class = Nvarpar) & (n^.left^.typ^.comp = Record);
- design(n^.left, x, rt); OPC.TypTest(x, n^.typ, TRUE, TRUE, VarRec)
- | Nproc:
- obj := n^.obj; x.mnolev := obj^.mnolev; x.mode := obj^.mode; x.offset := obj^.adr; x.adr := obj^.linkadr;
- x.reg := 0;
- IF x.mode = TProc THEN x.offset := (*mthno*) obj^.adr DIV 10000H; x.dmode := n^.subcl END
- | Ncommon:
- x := CommonDesign
- END;
- x.typ := n^.typ;
- IF (n^.typ^.comp = DynArr) & (x.dreg = -1) THEN OPC.DynArrItem(x, rt) END
- END design;
- PROCEDURE^ Call (n: OPT.Node; VAR res: OPL.Item; rt: LONGINT);
- PROCEDURE expr (n: OPT.Node; VAR x: OPL.Item; rt: LONGINT);
- VAR
- y, z: OPL.Item;
- f, subcl: SHORTINT;
- t: LONGINT;
- cval: OPT.Const;
- real: REAL;
- l: OPL.Label;
- BEGIN
- x.dreg := -1; y.dreg := -1; z.dreg := -1;
- CASE n^.class OF
- Nconst:
- x.typ := n^.typ; f := x.typ^.form; cval := n^.conval;
- CASE f OF
- Byte, Bool, Char, SInt, Int, LInt, NilTyp, Pointer:
- x.mode := Con; x.offset := cval^.intval
- | Set:
- x.mode := Con; x.offset := OPM.FlipBits(SYSTEM.VAL(LONGINT, cval^.setval))
- | String, Real, LReal:
- IF (n^.obj = NIL) OR (n^.obj^.conval^.intval = OPM.ConstNotAlloc) THEN
- IF f = String THEN OPL.AllocConst(cval^.ext^, cval^.intval2, x.offset, 4)
- ELSIF f = Real THEN real := SHORT(cval^.realval); FlipBytes(real); OPL.AllocConst(real, 4, x.offset, 4)
- ELSE (* LReal *) FlipBytes(cval^.realval); OPL.AllocConst(cval^.realval, 8, x.offset, 4)
- END;
- IF n^.obj # NIL THEN n^.obj^.conval^.intval := x.offset END
- ELSE x.offset := n^.obj^.conval^.intval
- END;
- x.mode := Var; x.mnolev := 0; x.adr := cval^.intval2
- END
- | Nupto:
- expr(n^.left, x, -1); expr(n^.right, y, -1); OPC.SetRange(x, y, rt)
- | Nmop: subcl := n^.subcl;
- IF subcl = not THEN l := x.Tjmp; x.Tjmp := x.Fjmp; x.Fjmp := l END;
- IF subcl IN {adr, val} THEN t := rt ELSE t := -1 END;
- expr(n^.left, x, t);
- CASE subcl OF
- not:
- OPC.Not(x, rt)
- | minus:
- OPC.Neg(x, rt)
- | is:
- y := x;
- OPC.TypTest(x, n^.obj^.typ, FALSE, FALSE, (n^.left^.class = Nvarpar) & (n^.left^.typ^.comp = Record))
- | conv:
- IF n^.typ^.form = Set THEN OPC.SetElem(x, rt)
- ELSE OPC.Convert(x, n^.typ, rt, TRUE)
- END
- | abs:
- OPC.Abs(x, rt)
- | cap:
- OPC.Cap(x, rt)
- | odd:
- OPC.Odd(x)
- | adr:
- OPC.SYSaddr(x, rt)
- | cc:
- OPM.err(300);
- | val:
- OPC.SYSval(x, x.typ^.form, n^.typ^.form)
- END
- | Ndop: subcl := n^.subcl;
- IF subcl = and THEN
- y.Fjmp := x.Fjmp; y.Tjmp := 0;
- expr(n^.left, y, -1);
- OPC.PutCondBranch(y, FALSE); OPC.SetLabel(y.Tjmp);
- x.Fjmp := y.Fjmp; expr(n^.right, x, -1)
- ELSIF subcl = or THEN
- y.Tjmp := x.Tjmp; y.Fjmp := 0; expr(n^.left, y, -1);
- OPC.PutCondBranch(y, TRUE); OPC.SetLabel(y.Fjmp);
- x.Tjmp := y.Tjmp; expr(n^.right, x, -1)
- ELSIF subcl = plus THEN
- IF n^.typ^.form IN RealTypes THEN
- IF n^.left^.subcl = times THEN
- expr(n^.left^.left, x, -1); expr(n^.left^.right, y, -1); expr(n^.right, z, -1); OPC.MulAdd(x, y, z, rt)
- ELSIF n^.right^.subcl = times THEN
- expr(n^.right^.left, x, -1); expr(n^.right^.right, y, -1); expr(n^.left, z, -1); OPC.MulAdd(x, y, z, rt)
- ELSE
- expr(n^.left, x, -1); expr(n^.right, y, -1); OPC.Plus(x, y, rt)
- END
- ELSE
- expr(n^.left, x, -1); expr(n^.right, y, -1); OPC.Plus(x, y, rt)
- END
- ELSIF subcl = minus THEN
- IF n^.typ^.form IN RealTypes THEN
- IF n^.left^.subcl = times THEN
- expr(n^.left^.left, x, -1); expr(n^.left^.right, y, -1); expr(n^.right, z, -1); OPC.MulSub(x, y, z, rt, FALSE)
- ELSIF n^.right^.subcl = times THEN
- expr(n^.right^.left, x, -1); expr(n^.right^.right, y, -1); expr(n^.left, z, -1); OPC.MulSub(x, y, z, rt, TRUE)
- ELSE
- expr(n^.left, x, -1); expr(n^.right, y, -1); OPC.Minus(x, y, rt)
- END
- ELSE
- expr(n^.left, x, -1); expr(n^.right, y, -1); OPC.Minus(x, y, rt)
- END
- ELSE
- expr(n^.left, x, -1); expr(n^.right, y, -1);
- CASE subcl OF
- times:
- OPC.Times(x, y, rt)
- | div:
- OPC.Div(x, y, rt)
- | slash:
- OPC.Slash(x, y, rt)
- | mod:
- OPC.Mod(x, y, rt)
- | in:
- OPC.In(x, y)
- | ash:
- OPC.Ash(x, y, rt)
- | lsh:
- OPC.SYSlsh(x, y, rt)
- | rot:
- OPC.SYSrot(x, y, rt)
- | msk:
- OPC.Msk(x, y, rt)
- | eql, neq, gtr, geq, lss, leq:
- OPC.Compare(x, y, subcl)
- | len:
- OPC.Len(x, y, rt)
- | bit:
- OPC.SYSbit(x, y)
- END
- END
- | Ncall:
- Call(n, x, rt)
- ELSE design(n, x, rt)
- END;
- IF ~powerpc & (n^.typ.form = Real) & (n^.class = Ndop) THEN (* binary real ops yield a LReal result on POWER *)
- x.typ := OPT.lrltyp
- ELSE x.typ := n^.typ
- END
- END expr;
- PROCEDURE Checkpc;
- BEGIN
- IF findpc & (OPL.pc*4 > OPM.breakpc) & OPM.noerr THEN OPM.err(255) END
- (* in the case of a call, the breakpc value shown in the trap viewer must point to the call instruction
- and not to the next instruction, i.e. breakpc # return address !! *)
- END Checkpc;
- PROCEDURE^ stat (n: OPT.Node);
- PROCEDURE IfStat (n: OPT.Node; withTrap: BOOLEAN);
- VAR ifn: OPT.Node; endlab: OPL.Label; x: OPL.Item;
- BEGIN
- endlab := 0; ifn := n^.left;
- IF withTrap & (ifn^.link = NIL) & (ifn^.left^.class = Nmop) & (ifn^.left^.subcl = is) THEN (* simple with statement *)
- ifn^.left^.class := Nguard; ifn^.left^.typ := ifn^.left^.obj^.typ;
- OPM.errpos := ifn^.conval^.intval; expr(ifn^.left, x, -1); Checkpc; OPC.With(x); stat(ifn^.right)
- ELSE
- LOOP
- x.Tjmp := 0; x.Fjmp := 0;
- OPM.errpos := ifn^.conval^.intval; expr(ifn^.left, x, -1); OPC.PutCondBranch(x, FALSE);
- OPC.SetLabel(x.Tjmp); Checkpc; stat(ifn^.right); ifn := ifn^.link;
- IF ifn = NIL THEN EXIT ELSE OPC.PutBranch(endlab); OPC.SetLabel(x.Fjmp) END
- END;
- IF withTrap OR (n^.right # NIL) THEN OPC.PutBranch(endlab); OPC.SetLabel(x.Fjmp);
- IF withTrap THEN OPC.Trap(TypeGuard); OPM.errpos := n^.conval^.intval; Checkpc ELSE stat(n^.right) END
- ELSE OPC.SetLabel(x.Fjmp)
- END;
- OPC.SetLabel(endlab)
- END
- END IfStat;
- PROCEDURE CaseStat (n: OPT.Node);
- VAR p, range: OPT.Node; x: OPL.Item; endlab: OPL.Label; table, base: LONGINT;
- BEGIN
- expr(n^.left, x, -1); p := n^.right; OPC.Case(x, p^.conval^.intval, p^.conval^.intval2, table); Checkpc;
- base := p^.conval^.intval; endlab := 0;
- IF p^.conval^.setval = {} THEN OPC.Trap(CaseTrap)
- ELSE stat(p^.right); OPC.PutBranch(endlab)
- END;
- p := p^.left;
- WHILE p # NIL DO
- range := p^.left;
- REPEAT
- OPL.FixCase(range^.conval^.intval-base, range^.conval^.intval2-base, table); range := range^.link
- UNTIL range = NIL;
- stat(p^.right);
- IF p^.link # NIL THEN OPC.PutBranch(endlab) END;
- p := p^.link
- END;
- OPC.SetLabel(endlab)
- END CaseStat;
- PROCEDURE Enter (n: OPT.Node);
- VAR
- p, v: OPT.Object;
- ralloc, falloc, calloc, fsize, adr: LONGINT;
- PROCEDURE Relocate (p: OPT.Object);
- VAR typ: OPT.Struct; form, comp, nrReg: LONGINT;
- BEGIN
- typ := p^.typ; form := typ^.form;
- IF p^.mode = VarPar THEN
- IF form = Comp THEN comp := typ^.comp;
- IF comp = DynArr THEN nrReg := typ^.n+2 ELSIF comp = Record THEN nrReg := 2 ELSE nrReg := 1 END
- ELSE nrReg := 1
- END;
- IF ralloc-nrReg > 11 THEN DEC(ralloc, nrReg); p^.linkadr := -1-(ralloc+1+Reg*32) END
- ELSE
- CASE form OF
- Byte, Char, SInt, Int, LInt, Set, Pointer:
- IF ralloc > 12 THEN p^.linkadr := -1-(ralloc+Reg*32); DEC(ralloc) END
- | Real, LReal:
- IF falloc > 13 THEN p^.linkadr := -1-(falloc+FReg*32); DEC(falloc) END
- | Bool:
- IF calloc > 7 THEN p^.linkadr := -1-(calloc+Cond*32); DEC(calloc) END
- | Comp:
- IF typ^.comp = DynArr THEN nrReg := typ^.n+2;
- IF ralloc-nrReg > 11 THEN DEC(ralloc, nrReg); p^.linkadr := -1-(ralloc+1+Reg*32) END
- END
- | ProcTyp:
- IF ralloc > 13 THEN DEC(ralloc, 2); p^.linkadr := -1-(ralloc+1+Reg*32) END
- ELSE
- END
- END
- END Relocate;
- BEGIN
- p := n^.obj;
- IF p # NIL THEN
- ralloc := 30; falloc := 31; calloc := 19; v := p^.link;
- WHILE v # NIL DO
- IF (v^.adr < 0) & v^.leaf THEN Relocate(v) END;
- v := v^.link
- END;
- v := p^.scope^.scope;
- WHILE v # NIL DO
- IF v^.leaf THEN Relocate(v) END;
- v := v^.link
- END;
- fsize := p^.conval^.intval2+(31-ralloc)*4+(31-falloc)*8+6*4; Align(fsize, 8);
- v := p^.link;
- WHILE v # NIL DO
- adr := v^.linkadr;
- IF (adr >= 0) & ((v^.mode = VarPar) OR (v^.typ^.form # Comp) OR (v^.typ^.comp = DynArr)) THEN
- v^.linkadr := adr-memTag+fsize
- END;
- v := v^.link
- END;
- INC(OPL.level);
- p^.conval^.intval := p^.conval^.intval+ralloc*1024+falloc*32+calloc;
- p^.conval^.intval2 := fsize-6*4
- END
- END Enter;
- PROCEDURE ActualPar (formal: OPT.Object; actual: OPT.Node);
- VAR
- dest, form, mode, rt, n: LONGINT;
- x, y, z, desc, tag: OPL.Item;
- typ, atyp: OPT.Struct;
- ParReg, ind: BOOLEAN;
- BEGIN
- WHILE formal # NIL DO
- dest := formal^.adr; typ := formal^.typ; form := typ^.form; atyp := actual^.typ;
- IF dest < 0 THEN rt := -1-dest; mode := rt DIV 32; rt := rt MOD 32; n := rt;
- IF ((typ^.form IN RealTypes) & (formal^.mode # VarPar)) # (atyp^.form IN RealTypes) THEN n := -1 END
- ELSE rt := -1; n := rt; mode := Based
- END;
- x.Tjmp := 0; x.Fjmp := 0;
- IF (atyp.comp = DynArr) & (rt > 0) THEN OPL.LockParR (rt + 1) END; (* mah error dynarr parameter on stack *)
- expr(actual, x, n);
- desc := x; x.dreg := -1; z := x;
- ind := (formal^.mode = VarPar) OR (form IN {String, Comp});
- IF ind THEN
- IF atyp^.comp # DynArr THEN OPC.LoadAddr(x, rt) ELSE tag := x END
- END;
- IF (formal^.mode = VarPar) & (typ = OPT.sysptrtyp) & (atyp # OPT.sysptrtyp) THEN
- tag.mode := Var; tag.typ := OPT.linttyp; tag.mnolev := -atyp^.BaseTyp^.mno;
- tag.offset := atyp^.BaseTyp^.tdadr;
- y.mode := Based; y.reg := x.reg; y.offset := 0; y.typ := OPT.linttyp; OPL.HoldTempR(x.reg); OPC.Assign(y, tag);
- OPL.UnholdTempR(x.reg)
- END;
- y := x;
- IF ~ind THEN y.typ := typ END;
- ParReg := dest < 0;
- IF ParReg THEN y.mode := SHORT(SHORT(mode)); y.reg := rt
- ELSE y.mode := Based; y.reg := SP; y.offset := dest
- END;
- IF atyp^.comp # DynArr THEN OPC.Assign(y, x) END;
- IF mode = Reg THEN
- OPL.LockParR(rt);
- IF form = ProcTyp THEN OPL.LockParR(rt+1) END
- ELSIF mode = FReg THEN
- OPL.LockParF(rt)
- END;
- IF (formal^.mode = VarPar) & (form = Comp) & (typ^.comp = Record) THEN
- IF actual^.class = Nderef THEN
- ASSERT(x.mode = Reg);
- x.mode := Based; x.offset := -4
- ELSIF actual^.class = Nvarpar THEN
- x := z; ASSERT(x.mode IN {Based, VarPar});
- IF x.mode = Based THEN x.mode := Reg; INC(x.reg) ELSE x.mode := Var; INC(x.offset, 4) END
- ELSE
- x.mode := Var; typ := actual^.typ; x.mnolev := -typ^.mno; x.offset := typ^.tdadr
- END;
- x.typ := OPT.linttyp; ASSERT(y.mode IN {Reg, Based});
- IF ParReg THEN INC(y.reg) ELSE INC(y.offset, 4) END;
- OPC.Assign(y, x);
- IF ParReg THEN OPL.LockParR(y.reg) END
- ELSIF (form = Comp) & (typ^.comp = DynArr) THEN
- IF atyp^.comp # DynArr THEN
- n := typ^.n; typ := typ^.BaseTyp;
- WHILE n >= 0 DO
- x.mode := Con; x.typ := OPT.linttyp;
- IF atyp^.form = String THEN x.offset := x.adr
- ELSIF typ^.form = Byte THEN x.offset := atyp^.size
- ELSE x.offset := atyp^.n
- END;
- IF ParReg THEN INC(y.reg) ELSE INC(y.offset, 4) END;
- OPC.Assign(y, x);
- IF ParReg THEN OPL.LockParR(y.reg) END;
- typ := typ^.BaseTyp; atyp := atyp^.BaseTyp; DEC(n)
- END
- ELSE
- dest := rt; z := y; (* dest of adr part *)
- n := typ^.n; typ := typ^.BaseTyp; x.typ := OPT.linttyp;
- y.typ := OPT.linttyp; mode := desc.dmode; x.mode := SHORT(SHORT(mode)); x.reg := desc.dreg;
- WHILE n >= 0 DO
- IF ParReg THEN INC(y.reg); rt := y.reg ELSE INC(y.offset, 4); rt := -1 END;
- IF typ^.form = Byte THEN
- x := desc; OPC.TypeSize(x, atyp, rt); ASSERT(n = 0);
- IF x.dreg # -1 THEN OPL.FreeTempR(x.dreg); x.dreg := -1 END
- ELSIF mode = Reg THEN x.reg := desc.dreg+atyp^.offset DIV 4
- ELSE x.mode := SHORT(SHORT(mode)); x.reg := desc.dreg; x.offset := desc.adr+atyp^.offset
- END;
- OPC.Assign(y, x);
- IF ParReg THEN OPL.LockParR(rt) END;
- typ := typ^.BaseTyp; atyp := atyp^.BaseTyp; DEC(n)
- END;
- OPC.LoadAddr(tag, dest); z.typ := OPT.linttyp; OPC.Assign(z, tag)
- END
- END;
- IF desc.dreg # -1 THEN OPL.UnholdTempR(desc.dreg); OPL.FreeTempR(desc.dreg) END;
- formal := formal^.link; actual := actual^.link
- END
- END ActualPar;
- PROCEDURE ArgSize (par: OPT.Object): LONGINT;
- VAR s: LONGINT; c: SHORTINT; typ: OPT.Struct;
- BEGIN s := 0;
- WHILE par # NIL DO
- typ := par^.typ; c := typ^.comp;
- IF c = DynArr THEN INC(s, typ^.size)
- ELSIF par^.mode = VarPar THEN
- IF c = Record THEN INC(s, 8) ELSE INC(s, 4) END
- ELSE
- IF c IN {Record, Array} THEN INC(s, 4)
- ELSIF typ^.form = LReal THEN INC(s, 8 + s MOD 8)
- ELSIF typ^.form = ProcTyp THEN INC(s, 8)
- ELSE INC(s, 4)
- END
- END;
- par := par^.link
- END;
- Align(s, 8); RETURN s*10000H
- END ArgSize;
- PROCEDURE Call (n: OPT.Node; VAR res: OPL.Item; rt: LONGINT);
- VAR
- x: OPL.Item;
- parSize, t: LONGINT;
- function: BOOLEAN;
- saved: OPL.SaveDesc;
- proc: OPT.Object;
- BEGIN
- INC(levCall); t := -1;
- (* IF n^.left^.class IN {Nfield, Nderef, Nindex} THEN OPL.LockParR(12); t := 12 END; *)
- (* design(n^.left, x, t); *) function := n^.typ^.form # NoTyp; (* << evaluation of designator delayed, 5.1.93 *)
- IF function THEN OPC.SaveRegisters(x, saved) END;
- ActualPar(n^.obj, n^.right);
- design(n^.left, x, -1);
- IF ~(x.mode IN {CProc, IProc}) THEN
- IF x.mode IN {LProc, XProc} THEN
- proc := n^.left^.obj; parSize := proc^.conval^.intval;
- IF parSize = -1 THEN parSize := ArgSize(proc^.link); proc^.conval^.intval := parSize END
- ELSE parSize := ArgSize((*n^.left^.typ^.link*)n^.obj)
- END;
- IF x.mode = TProc THEN OPC.GetMethod(x, n^.right^.typ, n^.obj^.typ^.form = Pointer, x.dmode = 1) END;
- OPC.Call(x, parSize DIV 10000H);
- IF x.mode IN {LProc, XProc} THEN n^.left^.obj^.adr := x.offset; n^.left^.obj^.linkadr := x.adr END
- ELSE OPM.err(299)
- END;
- IF function THEN
- res.typ := n.typ; res.dreg := -1;
- IF res.typ^.form IN {Real, LReal} THEN res.mode := FReg; res.reg := 1 ELSE res.mode := Reg; res.reg := 3 END;
- OPC.RestoreRegisters(res, saved, rt)
- END;
- IF levCall = 1 THEN OPL.FreePar END;
- DEC(levCall)
- END Call;
- PROCEDURE Dim (VAR x, nofel: OPL.Item; n: OPT.Node; typ: OPT.Struct; nofdim, rt: LONGINT);
- VAR
- len, y: OPL.Item;
- btyp: OPT.Struct;
- BEGIN rt := -1;
- IF (nofdim = 1) & (typ^.BaseTyp^.form IN {Byte, Bool, Char, SInt}) THEN rt := 4 END;
- expr(n, len, rt);
- IF nofdim = 1 THEN OPL.LockParR(3) (*tag*); OPL.LockParR(4) (*nofelem*); OPL.LockParR(5) (*nofdim*) END;
- IF len.mode # Con THEN OPC.Load(len, -1); OPL.HoldTempR(len.reg); OPC.GenDimTrap(len) END;
- IF nofdim = 1 THEN nofel := len ELSE OPC.MulDim(nofel, len, 4) END;
- IF n^.link # NIL THEN
- Dim(x, nofel, n^.link, typ^.BaseTyp, nofdim+1, rt)
- ELSE
- btyp := typ^.BaseTyp; rt := 1;
- WHILE btyp^.comp = Array DO
- rt := rt*btyp^.n; btyp := btyp^.BaseTyp
- END;
- IF rt # 1 THEN
- y.mode := Con; y.offset := rt; y.typ := OPT.linttyp; OPC.MulDim(nofel, y, 4)
- END;
- OPC.NewArr(x, nofel, nofdim, btyp, rt); OPL.HoldTempR(x.reg);
- END;
- ASSERT(x.mode = Reg);
- y := x; y.mode := Based; y.offset := 8;
- OPC.SetDim(y, len, typ);
- IF nofdim = 1 THEN OPL.UnholdTempR(x.reg) END;
- END Dim;
- PROCEDURE stat (n: OPT.Node);
- VAR
- x, y, z: OPL.Item;
- rt, subcl: LONGINT;
- l: OPL.Label;
- var, adr: OPT.Node;
- s: ARRAY 64 OF CHAR;
- tmpStats : Stats; (* debugger info *)
- BEGIN
- WHILE n # NIL DO OPM.errpos := n^.conval^.intval; (* OPL.BegStat *)
- x.Tjmp := 0; x.Fjmp := 0; y.Tjmp := 0; y.Fjmp := 0; z.Tjmp := 0; z.Fjmp := 0;
- IF findpc THEN (* debugger infos *)
- IF (lastClass # Nifelse) & (n^.class # Nwhile) & (n^.class # Nrepeat) THEN
- IF stats = NIL THEN NEW (stats); curStats := stats END;
- IF curStats.numStat = 128 THEN tmpStats := curStats; NEW (curStats); tmpStats.next := curStats END;
- IF n^.class # Nenter THEN
- curStats.pc[curStats.numStat] := SHORT (SHORT (OPL.pc - decPC)); decPC := OPL.pc;
- curStats.pos[curStats.numStat] := lastErr;
- INC (curStats.numStat)
- END
- END;
- lastClass := n^.class;
- lastErr := OPM.errpos
- END;
- CASE n^.class OF
- Nenter:
- Enter(n); stat(n^.left); OPC.Enter(n^.obj); stat(n^.right);
- IF findpc THEN
- IF curStats.numStat = 128 THEN tmpStats := curStats; NEW (curStats); tmpStats.next := curStats END;
- curStats.pc[curStats.numStat] := SHORT (SHORT (OPL.pc - decPC)); decPC := OPL.pc;
- curStats.pos[curStats.numStat] := lastErr;
- INC (curStats.numStat)
- END;
- OPC.Leave(n^.obj);
- IF n^.obj # NIL THEN
- DEC(OPL.level);
- IF n^.obj^.mode = TProc THEN
- rt := 0; subcl := 0;
- COPY(n^.obj^.link^.typ^.strobj^.name, s);
- WHILE s[rt] # 0X DO INC(rt) END;
- s[rt] := "."; INC(rt);
- REPEAT s[rt] := n^.obj^.name[subcl]; INC(rt); INC(subcl) UNTIL s[rt-1] = 0X;
- OPL.OutRefName(s)
- ELSE
- OPL.OutRefName(n^.obj^.name)
- END;
- OPL.OutRefs(n^.obj^.scope^.right)
- ELSE
- OPL.OutRefName("$$"); OPL.OutRefs(OPT.topScope)
- END;
- | Ninittd:
- (* done at load time *)
- | Nassign:
- subcl := n^.subcl;
- IF subcl = movefn THEN
- expr(n^.right^.link, z, -1); expr(n^.right, y, -1); expr(n^.left, x, -1);
- OPC.SYSmove(x, y, z)
- ELSIF subcl = newfn THEN
- IF n^.right # NIL THEN (* open array *)
- Dim(y, (*nofel*)z, n^.right, n^.left^.typ^.BaseTyp, 1, -1)
- ELSE
- OPC.NewRec(y, n^.left^.typ^.BaseTyp, -1)
- END;
- design(n^.left, x, -1); OPC.Assign(x, y)
- ELSE
- IF subcl IN {getfn, putfn} THEN
- IF subcl = getfn THEN var := n^.left; adr := n^.right
- ELSE var := n^.right; adr := n^.left
- END;
- z.mode := Con; z.typ := OPT.linttyp; z.offset := 0;
- IF adr^.class = Ndop THEN
- IF adr^.subcl = plus THEN expr(adr^.left, x, -1); expr(adr^.right, z, -1)
- ELSIF (adr^.subcl = minus) & (adr^.right^.class = Nconst) THEN
- expr(adr^.left, x, -1); expr(adr^.right, z, -1); z.offset := -z.offset
- ELSE expr(adr, x, -1)
- END
- ELSE
- expr(adr, x, -1)
- END;
- expr(var, y, -1)
- ELSE
- expr(n^.left, x, -1);
- IF DoCommonDesign & (subcl = assign) & (n^.right^.class IN {Nmop, Ndop}) &
- SameDesign(n^.left, n^.right^.left) THEN
- OPC.CommonDesign(x); CommonDesign := x;
- CommonDesignClass := n^.right^.left^.class;
- n^.right^.left^.class := Ncommon
- END
- END;
- IF subcl = sysnewfn THEN rt := 3
- ELSIF (x.mode IN {Reg, FReg}) & (subcl = assign) &
- ((x.mode = FReg) = (n^.right^.typ^.form IN RealTypes)) THEN rt := x.reg
- ELSE rt := -1
- END;
- y.Tjmp := 0; y.Fjmp := 0;
- IF ~(subcl IN {newfn, getfn, putfn}) THEN expr(n^.right, y, rt);
- IF (n^.right^.left # NIL) & (n^.right^.left^.class = Ncommon) THEN
- OPC.UnholdCommonDesign(CommonDesign); n^.left^.class := CommonDesignClass
- END
- END;
- CASE subcl OF
- assign:
- OPC.Assign(x, y)
- | incfn, decfn:
- OPC.Increment(x, y, subcl = incfn)
- | inclfn:
- OPC.Include(x, y)
- | exclfn:
- OPC.Exclude(x, y)
- | getfn:
- OPC.SYSget(x, z, y)
- | putfn:
- OPC.SYSput(x, z, y)
- | getrfn:
- OPC.SYSgetreg(x, y)
- | putrfn:
- OPC.SYSputreg(x, y)
- | newfn:
- | sysnewfn:
- IF x.mode = Reg THEN rt := x.reg ELSE rt := -1 END;
- OPC.NewSys(z, y, rt); OPC.Assign(x, z)
- | copyfn:
- OPC.Copy(x, y)
- END
- END
- | Nwhile:
- l := 0; OPC.SetLabel(l); x.Tjmp := 0; x.Fjmp := 0; expr(n^.left, x, -1); OPC.PutCondBranch(x, FALSE);
- OPC.SetLabel(x.Tjmp); Checkpc;
- stat(n^.right); OPC.PutBranch(l); OPC.SetLabel(x.Fjmp)
- | Nrepeat:
- x.Fjmp := 0; OPC.SetLabel(x.Fjmp); stat(n^.left); x.Tjmp := 0; expr(n^.right, x, -1);
- OPC.PutCondBranch(x, FALSE); OPC.SetLabel(x.Tjmp)
- | Nloop:
- OPC.EnterLoop; stat(n^.left); OPC.EndLoop
- | Nexit:
- OPC.ExitLoop
- | Ncall:
- Call(n, x, -1)
- | Nifelse:
- IF (n^.subcl # assertfn) OR assert THEN IfStat(n, FALSE) END
- | Ncase:
- CaseStat(n)
- | Nwith:
- IfStat(n, n^.subcl = 0)
- | Nreturn:
- IF n^.left # NIL THEN
- IF n^.obj^.typ^.form IN {Real, LReal} THEN rt := 1; x.mode := FReg ELSE rt := 3; x.mode := Reg END;
- y.Tjmp := 0; y.Fjmp := 0; y.dreg := -1;
- expr(n^.left, y, rt); x.typ := n^.obj^.typ; x.reg := rt; OPC.Assign(x, y)
- ELSE x.mode := Head
- END;
- OPC.Return(x)
- | Ntrap:
- OPC.Trap(SHORT(n^.right^.conval^.intval))
- END;
- Checkpc; OPL.EndStat; n := n^.link
- END
- END stat;
- PROCEDURE Module* (prog: OPT.Node);
- BEGIN levCall := 0; stat(prog);
- IF findpc & OPM.noerr THEN OPM.err(254) END
- END Module;
- PROCEDURE Init* (opt: SET; bpc: LONGINT);
- CONST ass = 8; fpc = 9; ppc = 10;
- BEGIN
- decPC := 0; stats := NIL; lastErr := OPM.errpos; lastClass := Ncall; (* debug info *)
- assert := ass IN opt; findpc := fpc IN opt; powerpc := ppc IN opt;
- IF findpc THEN OPM.breakpc := bpc ELSE OPM.breakpc := MAX(LONGINT) END
- END Init;
- END POPV.
- IF findpc THEN (* debugger infos *)
- IF (n^.class#Nwhile) & (n^.class#Nrepeat) & (n^.class#Nifelse) & (n^.class#Ncase) THEN
- IF stats = NIL THEN NEW (stats); curStats := stats END;
- IF curStats.numStat = 128 THEN tmpStats := curStats; NEW (curStats); tmpStats.next := curStats END;
- IF n^.class # Nenter THEN
- curStats.pc[curStats.numStat] := SHORT (SHORT (OPL.pc - decPC)); decPC := OPL.pc;
- curStats.pos[curStats.numStat] := OPM.errpos;
- INC (curStats.numStat)
- END;
- END
- END;
-